package com.us.simple.common.interceptor;


import com.auth0.jwt.interfaces.DecodedJWT;
import com.us.simple.common.context.RequestContextHolder;
import com.us.simple.common.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义拦截器
 *
 * @Author: wangziqian
 * @Date: 2024-05-15
 */
@Slf4j
public class JwtInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 判断处理器是否为方法处理器的实例，如果不是，则直接放行。
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        // 2. 从请求头中获取"Authorization"字段，此处存放着JWT令牌。
        String token = request.getHeader("token");
        if (null == token){
            throw new RuntimeException("请填写token!");
        }
        try {
            // 3. 使用JwtUtil的parseJWT方法解析token
            DecodedJWT verify = JwtUtil.verify(token);

            // 4. 从 verify 中获取用户ID，这是存放在token中的一个自定义声明。
            String id = verify.getClaim("userid").asString();
            String name = verify.getClaim("username").asString();
            log.info("当前操作人id={},登录名={}", id,name);

            RequestContextHolder.set("username", name);

            // 5. 检查Redis中是否存在以adminTokenKey + "-" + userId为key的数据，以验证token的有效性。
            //Boolean redisResult = redisTemplate.hasKey(adminTokenKey + "-" + userId);

            // 6. 如果在Redis中找不到对应的key，说明token无效。
            //if (!redisResult) {
            // response.setStatus(401); // 设置HTTP状态码为401，表示未授权。
            // throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "Invalid Token"); // 抛出业务异常。
            // }

            // 7. 如果验证通过，则返回true，继续执行请求。
            return true;
        } catch (Exception exception) {
            log.error(exception.getMessage());
            throw new RuntimeException("token已失效!");
        }
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {
        // 请求处理完成，清除上下文
        RequestContextHolder.clearContext();
    }

}
